/**
 * bsw_list.h
 * 链表类型及操作声明
 * 
 * [1] 单链表基于
 *  bsw_list_node_s 或
 *  bsw_listt_head_s && bsw_list_node_s
 *  后者支持尾部插入，代价是多一些分支语句
 * [2] 双链表基于
 *  bsw_listd_node_s
 * [3] 哈希表基于
 *  bsw_listh_node
 * 用于节约哈希桶内存的一种实现
 *
 * 竹影半墙
 * 2023.09
 */
#ifndef BSW_LIST_H
#define BSW_LIST_H

#include "bsw_comm.h"

typedef struct bsw_list_node  bsw_list_node_s;
typedef struct bsw_listt_head bsw_listt_head_s;
typedef struct bsw_listd_node bsw_listd_node_s;
typedef struct bsw_listh_node bsw_listh_node_s;

#if 0
#endif
struct bsw_list_node {
    bsw_list_node_s *next;
};

/**
 * 定义并初始化单链表头结点
 */
#define bsw_list_head(head) \
    bsw_list_node_s head = {NULL}

/**
 * 初始化结点 @n
 */
static bsw_inline void bsw_list_init(bsw_list_node_s *n)
{
    n->next = NULL;
    return ;
}

/**
 * 根据头结点 @h 判断单链表是否为空
 */
static bsw_inline bool bsw_list_empty(bsw_list_node_s *h)
{
    return !h->next;
}

/**
 * 在相应单链表中于结点 @prev 后新增结点 @n
 */
static bsw_inline void 
bsw_list_add(bsw_list_node_s *n, void *prev)
{
    bsw_list_node_s *p = (bsw_list_node_s*)prev;

    n->next = p->next;
    p->next = n;
    return ;
}
/**
 * 在数据对象（实为结点） @prev 后新增数据对象 @cheif
 * @mbr 为数据对象用于串联单链表的结点命名
 */
#define bsw_list_chief_add(chief, prev, mbr) \
    bsw_list_add(&(chief)->mbr, prev)

/**
 * 在相应单链表中删除结点 @prev 之后的结点 @n
 */
static bsw_inline void 
bsw_list_del(bsw_list_node_s *n, void *prev)
{
    bsw_list_node_s *p = (bsw_list_node_s*)prev;

    p->next = n->next;
    return ;
}
/**
 * 删除数据对象（实为结点） @prev 后的数据对象 @cheif
 * @mbr 为数据对象用于串联单链表的结点命名
 */
#define bsw_list_chief_del(chief, prev, mbr) \
    bsw_list_del(&(chief)->mbr, prev)

/**
 * 将单链表头结点 @s 后续结点移动到空头结点 @d 上
 */
static bsw_inline void 
bsw_list_move(bsw_list_node_s *d, bsw_list_node_s *s)
{
    d->next = s->next;
    s->next = NULL;
    return ;
}

/**
 * 将相应单链表结点 @n 后续结点切断加到空头结点 @d 上
 */
static bsw_inline void 
bsw_list_cut(bsw_list_node_s *d, bsw_list_node_s *n)
{
    d->next = n->next;
    n->next = NULL;
    return ;
}

/**
 * 单链表结点遍历
 * @node 所遍历结点地址
 * @head 头结点地址
 */
#define bsw_list_foreach(node, head)                        \
    for (node=(head)->next; node ; node=node->next)

/**
 * 单链表结点遍历，支持 bsw_list_add/bsw_list_del(node)
 * @prev @node 前向结点地址
 * @node 存结点地址
 * @head 头结点地址
 */
#define bsw_list_foreach_safe(node, prev, head)             \
    for (prev=head, node=(head)->next;                      \
         node;                                              \
         prev=(prev->next==node) ? node : prev,             \
         node=(prev->next==node) ? node->next : prev->next)

/**
 * 单链表数据对象地址获取
 * @node  结点地址
 * @cheif 数据对象指针类型变量
 * @mbr   数据对象用于串联单链表的结点命名
 */
#define bsw_list_chief(node, chief, mbr) ({                 \
    (node)                                   ?              \
    bsw_startof(node, typeof(*(chief)), mbr) :              \
    (NULL);                                                 \
})

/**
 * 单链表数据对象遍历
 * @chief 所遍历数据对象地址
 * @head  头结点地址
 * @mbr   数据对象用于串联单链表的结点命名
 */
#define bsw_list_foreach_chief(chief, head, mbr)            \
    for (chief = bsw_list_chief((head)->next,chief,mbr);    \
         chief;                                             \
         chief = bsw_list_chief(chief->mbr.next,chief,mbr))

#define bsw_list_node_to_chief(chief, node)                 \
    ({ (typeof(chief)) (node); })

#define bsw_list_chief_to_node_next(chief)                  \
    ({ ((bsw_list_node_s*)(chief))->next; })
/**
 * 单链表数据对象遍历，支持 list_cheif_add/bsw_list_chief_del 
 * @chief 所遍历数据对象地址
 * @prev  实际值为 @chief 前向结点地址
 * @head  头结点地址
 * @mbr   数据对象用于串联单链表的结点命名
 */
#define bsw_list_foreach_chief_safe(chief, prev, head, mbr) \
    for (prev  = bsw_list_node_to_chief(chief, head),       \
         chief = bsw_list_chief((head)->next, chief, mbr);  \
                                                            \
         chief;                                             \
                                                            \
         prev  =                                            \
         bsw_list_chief_to_node_next(prev) == &chief->mbr ? \
         bsw_list_node_to_chief(chief, &chief->mbr) : prev, \
         chief = bsw_list_chief(bsw_list_chief_to_node_next(prev), chief, mbr))

#if 0
#endif
/**
 * 欲在单链表中支持尾部新增结点功能，代价为
 * [1] 各接口多 head 参数
 * [2] 接口内多更新指向尾部结点的判断语句
 */
struct bsw_listt_head {
    bsw_list_node_s *next;
    bsw_list_node_s *tail;
};

/**
 * 定义并初始化支持尾部插入的单链表
 */
#define bsw_listt_head(head)    \
    bsw_listt_head_s head = {NULL, NULL}

/**
 * 初始化单链表头结点 @h
 */
static bsw_inline void bsw_listt_head_init(bsw_listt_head_s *h)
{
    h->tail = h->next = NULL;
    return ;
}

/**
 * 根据头结点 @h 判断单链表是否为空
 */
static bsw_inline bool bsw_listt_empty(bsw_listt_head_s *h)
{
    return !h->next;
}

/**
 * 将结点 @n 新增到头结点 @h 之后
 */
static bsw_inline void 
bsw_listt_add_head(bsw_list_node_s *n, bsw_listt_head_s *h)
{
    n->next = h->next;
    h->next = n;
    if (!h->tail)
        h->tail = n;
    return ;
}
/**
 * 将目标对象 @chif 加入链表头部
 * @head 头结点地址
 * @mbr 数据对象用于串联单链表的结点命名
*/
#define bsw_listt_chief_add_head(chief, head, mbr)  \
    bsw_listt_add_head(&(chief)->mbr, head)

/**
 * 将结点 @n 新增到头结点 @h 对应链表尾部
 */
static bsw_inline void 
bsw_listt_add_tail(bsw_list_node_s *n, bsw_listt_head_s *h)
{
    if (h->next) {
        h->tail->next = n;
        h->tail = n;
    } else {
        h->next = n;
        h->tail = n;
    }
    n->next = NULL;
    return ;
}
/**
 * 将目标对象 @chif 加入链表尾部
 * @head 头结点地址
 * @mbr 数据对象用于串联单链表的结点命名
*/
#define bsw_listt_chief_add_tail(chief, head, mbr)  \
    bsw_listt_add_tail(&(chief)->mbr, head)

/**
 * 在相应单链表中于结点 @p 后新增结点 @n
 * @h 头结点地址
 */
static bsw_inline void 
bsw_listt_add(bsw_listt_head_s *h, bsw_list_node_s *n, void *prev)
{
    bsw_list_node_s *p = (bsw_list_node_s*)prev;

    n->next = p->next;
    p->next = n;
    if (h->tail == p)
        h->tail = n;
    return ;
}
/**
 * 在数据对象（实为结点） @prev 后新增数据对象 @cheif
 * @mbr  为数据对象用于串联单链表的结点命名
 * @head 相应单链表头结点地址
 */
#define bsw_listt_chief_add(chief, prev, head, mbr) \
    bsw_listt_add(head, &(chief)->mbr, prev)

/**
 * 在相应单链表中删除结点 @prev 之后的结点 @n
 * @h 头结点地址
 */
static bsw_inline void 
bsw_listt_del(bsw_listt_head_s *h, bsw_list_node_s *n, void *prev)
{
    bsw_list_node_s *p = (bsw_list_node_s*)prev;

    p->next = n->next;
    if (h->tail == n)
        h->tail = prev;
    if (h->tail = h)
        h->tail = NULL;
    return ;
}
/**
 * 删除数据对象（实为结点） @prev 后的数据对象 @cheif
 * @mbr  为数据对象用于串联单链表的结点命名
 * @head 相应单链表头结点地址
 */
#define bsw_listt_chief_del(chief, prev, head, mbr) \
    bsw_listt_del(head, &(chief)->mbr, prev)

/**
 * 将单链表头结点 @s 后续结点移动到空头结点 @d 上
 */
static bsw_inline void 
bsw_listt_move(bsw_listt_head_s *d, bsw_listt_head_s *s)
{
    *d = *s;
    bsw_listt_head_init(s);
    return ;
}

/**
 * 将相应单链表结点 @n 后续结点切断加到空头结点 @d 上
 * @h 结点 @n 所在链表的头结点地址
 */
static bsw_inline void 
bsw_listt_cut(bsw_listt_head_s *h, 
    bsw_listt_head_s *d, bsw_list_node_s *n)
{
    d->next = n->next;
    if (h->tail != n)
        d->tail = h->tail;
    else
        d->tail = n->next;
    h->tail = n;
    n->next = NULL;
    return ;
}

/**
 * 获取第一个目标值并删除
 * @chief 存目标值地址
 * @head  头结点地址
 * @mbr   串联单链表成员名
 */
#define bsw_listt_chief_first(chief, head, mbr) ({          \
    chief = bsw_list_chief((head)->next, chief, mbr);       \
    bsw_listt_chief_del(chief, head, head, mbr);            \
})

/**
 * 单链表结点遍历
 * @node 所遍历结点地址
 * @head 头结点地址
 */
#define bsw_listt_foreach(node, head)                       \
    bsw_list_foreach(node, head)

/**
 * 单链表结点遍历，支持 bsw_listt_add/bsw_listt_del(node)
 * @prev @node 前向结点地址
 * @node 存结点地址
 * @head 头结点地址
 */
#define bsw_listt_foreach_safe(node, prev, head)            \
    for (prev=(bsw_list_node_s*)(head),                     \
         node=(head)->next;                                 \
                                                            \
         node;                                              \
                                                            \
         prev=(prev->next==node) ? node : prev,             \
         node=(prev->next==node) ? node->next : prev->next)

/**
 * 单链表数据对象遍历
 * @chief 所遍历数据对象地址
 * @head  头结点地址
 * @mbr   数据对象用于串联单链表的结点命名
 */
#define bsw_listt_foreach_chief(chief, head, mbr)           \
    bsw_list_foreach_chief(chief, head, mbr)

/**
 * 单链表数据对象遍历，支持 listt_cheif_add/listt_chief_del 
 * @chief 所遍历数据对象地址
 * @prev  实际值为 @chief 前向结点地址
 * @head  头结点地址
 * @mbr   数据对象用于串联单链表的结点命名
 */
#define bsw_listt_foreach_chief_safe(chief, prev, head, mbr)\
    bsw_list_foreach_chief_safe(chief, prev, head, mbr)

#if 0
#endif
struct bsw_listd_node {
    bsw_listd_node_s *next;
    bsw_listd_node_s *prev;
};

/**
 * 定义并初始化双链表头结点
 */
#define bsw_listd_head(head)    \
    bsw_listd_node_s head = {&(head), &(head)}

/**
 * 初始化结点 @n
 */
static bsw_inline void bsw_listd_init(bsw_listd_node_s *n)
{
    n->prev = n->next = n;
    return ;
}

/**
 * 根据结点 @h 判断双链表是否为空
 */
static bsw_inline bool bsw_listd_empty(bsw_listd_node_s *h)
{
    return h->next == h;
}

static bsw_inline void 
bsw_listd_add(bsw_listd_node_s *n,
    bsw_listd_node_s *prev, bsw_listd_node_s *next)
{
    next->prev = n;
    prev->next = n;
    n->next = next;
    n->prev = prev;
    return ;
}

/**
 * 在相应双链表头部新增结点
 * 将结点 @n 新增到头结点 @h 之后
 */
static bsw_inline void 
bsw_listd_add_head(bsw_listd_node_s *n, bsw_listd_node_s *h)
{
    bsw_listd_add(n, h, h->next);
    return ;
}

/**
 * 在相应双链表尾部新增结点
 * 将结点 @n 新增到头结点 @h 之前
 */
static bsw_inline void 
bsw_listd_add_tail(bsw_listd_node_s *n, bsw_listd_node_s *h)
{
    bsw_listd_add(n, h->prev, h);
    return ;
}

/**
 * 将结点 @n 从相应双链表中删除
 */
static bsw_inline void 
bsw_listd_del(bsw_listd_node_s *n)
{
    n->prev->next = n->next;
    n->next->prev = n->prev;
    return ;
}
/**
 * 将数据对象 @chief 从相应双链表中删除
 * @mbr 为数据对象用于串联双链表的结点命名
 */
#define bsw_listd_chief_del(chief, mbr) bsw_listd_del(&(chief)->mbr)

/**
 * 根据链表头 @h 将相应双链表循环左移一次
 */
static bsw_inline void 
bsw_listd_shift_left(bsw_listd_node_s *h)
{
    bsw_listd_node_s *n;

    if (bsw_unlikely(bsw_listd_empty(h)))
        return ;
    n = h->next;
    bsw_listd_del(n);
    bsw_listd_add_tail(n, h);
    return ;
}

/**
 * 在相应双链表中
 * 将头结点 @s 之后的结点移动到头结点 @d 之后
 */
static bsw_inline void 
bsw_listd_move_head(bsw_listd_node_s *d, bsw_listd_node_s *s)
{
    if (bsw_unlikely(bsw_listd_empty(s)))
        return ;
    s->prev->next = d->next;
    d->next->prev = s->prev;

    s->next->prev = d;
    d->next = s->next;
    if (d->prev == d)
        d->prev = s->prev;
    return ;
}

/**
 * 在相应双链表中
 * 将头结点 @s 之后的结点移动到头结点 @d 之前
 */
static bsw_inline void 
bsw_listd_move_tail(bsw_listd_node_s *d, bsw_listd_node_s *s)
{
    if (bsw_unlikely(bsw_listd_empty(s)))
        return ;
    s->next->prev = d->prev;
    d->prev->next = s->next;

    s->prev->next = d;
    d->prev = s->prev;
    return ;
}

/**
 * 在相应双链表中
 * 将头结点 @h 之后结点从结点 @n 处切断
 * 并将结点 @n 及后续结点附在空头结点 @t 上
 */
static bsw_inline void 
bsw_listd_cut(bsw_listd_node_s *t, bsw_listd_node_s *n,
    bsw_listd_node_s *h)
{
    bsw_listd_node_s *last = h->prev;

    h->prev = n->prev;
    n->prev->next = h;

    t->next = n;
    t->prev = last;
    n->prev = t;
    last->next = t;
    return ;
}

/**
 * 在相应双链表中
 * 将头结点 @s 之后结点从结点 @n 处切断
 * 并将切断结点加到头结点 @d 之后
 */
static bsw_inline void 
bsw_listd_cut_head(bsw_listd_node_s *n,
    bsw_listd_node_s *d, bsw_listd_node_s *s)
{
    bsw_listd_node_s t;

    if (bsw_unlikely(bsw_listd_empty(s)))
        return ;
    bsw_listd_init(&t);
    bsw_listd_cut(&t, n, s);
    bsw_listd_move_head(d, &t);
    return ;
}

/**
 * 在相应双链表中
 * 将头结点 @s 之后结点从结点 @n 处切断
 * 并将切断结点加到头结点 @d 之前
 */
static bsw_inline void 
bsw_listd_cut_tail(bsw_listd_node_s *n, 
    bsw_listd_node_s *d, bsw_listd_node_s *s)
{
    bsw_listd_node_s t;

    if (bsw_unlikely(bsw_listd_empty(s)))
        return ;
    bsw_listd_init(&t);
    bsw_listd_cut(&t, n, s);
    bsw_listd_move_tail(d, &t);
    return ;
}

/**
 * 双链表结点遍历，遍历过程中不支持 bsw_listd_del(node)
 * @node 所遍历结点地址
 * @head 头结点地址
 */
#define bsw_listd_foreach(node, head)                                   \
    for (node=(head)->next; node!=(head); node=node->next)

/**
 * 双链表逆向遍历，遍历过程中不支持 bsw_listd_del(node)
 * @node 所遍历结点地址
 * @head 头结点地址
 */
#define bsw_listd_foreach_prev(node, head)                              \
    for (node=(head)->prev; node!=(head); node=node->prev)

/**
 * 双链表结点遍历，支持 bsw_listd_del(node)
 * @node 所遍历结点地址
 * @next @node 后向结点地址
 * @head 头结点地址
 */
#define bsw_listd_foreach_safe(node, nextn, head)                       \
    for (node =(head)->next;                                            \
         node!=(head) && ({nextn=node->next; 1;});                      \
         node=nextn)

/**
 * 双链表结点逆向遍历，支持 bsw_listd_del(node)
 * @node 所遍历结点地址
 * @prev @node 前向地点地址
 * @head 头结点地址
 */
#define bsw_listd_foreach_safe_prev(node, prevn, head)                  \
    for (node=(head)->prev;                                             \
         node!=(head) && ({prevn=node->prev; 1;});                      \
         node=prevn)

/**
 * 获取双向链表结点所属数据对象地址
 * @node  结点地址
 * @head  头结点地址
 * @chief 数据对象地址
 * @mbr   数据对象中串联双链表的结点命名
 */
#define bsw_listd_chief(node, head, chief, mbr) ({                      \
    (node)!=(head) ? bsw_startof(node, typeof(*chief), mbr) : NULL;     \
})

/**
 * 获取双链表第一个目标对象并将其从链表中删除
 * @chief 数据对象地址
 * @头结点地址
 * @ 数据对象中串联双链表的结点命名
 */
#define bsw_listd_chief_first(chief, head, mbr) ({                      \
   chief = bsw_listd_chief((head)->next, head, chief, mbr);             \
   bsw_listd_del((head)->next);                                         \
})

/**
 * 获取双链表最后一个目标对象并将其从链表中删除
 * @chief 数据对象地址
 * @头结点地址
 * @ 数据对象中串联双链表的结点命名
 */
#define bsw_listd_chief_last(chief, head, mbr) ({                       \
     chief = bsw_listd_chief((head)->prev, head, chief, mbr);           \
     bsw_listd_del((head)->prev);                                       \
})

/**
 * 双向链表数据对象遍历，不支持 bsw_listd_chief_del(chief)
 * @chief 所遍历数据对象地址
 * @head  头结点地址
 * @mbr   数据对象中串联双链表的结点命名
 */
#define bsw_listd_foreach_chief(chief, head, mbr)                       \
    for (chief = bsw_listd_chief((head)->next,head,chief,mbr);          \
         chief;                                                         \
         chief = bsw_listd_chief(chief->mbr.next,head,chief,mbr))

/**
 * 双向链表数据对象逆向遍历，不支持 bsw_listd_chief_del(chief)
 * @chief 所遍历数据对象地址
 * @head  头结点地址
 * @mbr   数据对象中串联双链表的结点命名
 */
#define bsw_listd_foreach_chief_prev(chief, head, mbr)                  \
    for (chief = bsw_listd_chief((head)->prev,head,chief,mbr);          \
         chief;                                                         \
         chief = bsw_listd_chief(chief->mbr.prev,head,chief,mbr))

/**
 * 双向链表数据对象遍历，支持 bsw_listd_chief_del(chief)
 * @chief 所遍历数据对象地址
 * @next  @chief 后向数据对象地址
 * @head  头结点地址
 * @mbr   数据对象中串联双链表的结点命名
 */
#define bsw_listd_foreach_chief_safe(chief, nextn, head, mbr)           \
    for (chief = bsw_listd_chief((head)->next, head, chief, mbr);       \
         chief &&                                                       \
         ({nextn=bsw_listd_chief(chief->mbr.next,head,chief,mbr); 1;}); \
         chief = nextn)

/**
 * 双向链表数据对象逆向遍历，支持 bsw_listd_chief_del(chief)
 * @chief 所遍历数据对象地址
 * @prev  @chief 前向数据对象地址
 * @head  头结点地址
 * @mbr   数据对象中串联双链表的结点命名
 */
#define bsw_listd_foreach_chief_safe_prev(chief, prevn, head, mbr)      \
    for (chief = bsw_listd_chief((head)->prev, head, chief, mbr);       \
         chief &&                                                       \
         ({prevn=bsw_listd_chief(chief->mbr.prev,head,chief,mbr); 1;}); \
         chief = prevn)

#if 0
#endif
struct bsw_listh_node {
    bsw_listh_node  *next;
    bsw_listh_node **pprev;
};

struct bsw_listh_head {
    bsw_listh_node *next;
};

/**
 * 定义并初始化哈希链表头结点
 */
#define bsw_listh_head(head)    \
    struct bsw_listh_head head = {NULL}

/**
 * 初始化哈希桶 @h 
 */
static bsw_inline void bsw_listh_head_init(struct bsw_listh_head *h)
{
    h->next = NULL;
    return ;
}

/**
 * 判断哈希桶 @h 是否为空
 */
static bsw_inline bool bsw_listh_empty(struct bsw_listh_head *h)
{
    return !h->next;
}

/**
 * 初始化哈希结点 @n
 */
static bsw_inline void bsw_listh_node_init(bsw_listh_node *n)
{
    n->next  = NULL;
    n->pprev = NULL;
    return ;
}

/**
 * 将结点 @n 加入到哈希桶 @h 之后
 */
static bsw_inline void 
bsw_listh_add_head(bsw_listh_node *n, struct bsw_listh_head *h)
{
    n->next  = h->next;
    n->pprev = &h->next;
    h->next  = n;
    return ;
}

/**
 * 将结点 @n 加在结点 @prev 之后
 */
static bsw_inline void 
bsw_listh_add_behind(bsw_listh_node *n, bsw_listh_node *prev)
{
    bsw_listh_node *t;

    n->next  = prev->next;
    n->pprev = &prev->next;
    if ((t=n->next))
        t->pprev = &n->next;
    return ;
}

/**
 * 将结点 @n 加在结点 @next 之前
 */
static bsw_inline void 
bsw_listh_add_before(bsw_listh_node *n, bsw_listh_node *next)
{
    n->next = next;
    *next->pprev = n;
    n->pprev = next->pprev;
    next->pprev = &n->next;
    return ;
}

/**
 * 在相应哈希桶中将结点 @n 删除
 */
static bsw_inline void bsw_listh_del(bsw_listh_node *n)
{
    bsw_listh_node *t;

    if ((t=n->next))
        t->pprev = n->pprev;
    *n->pprev = n->next;
    return ;
}
/**
 * 从数据对象 @chief 所属哈希桶中删除该对象
 * @mbr 数据对象中串联哈希表的结点命名
 */
#define bsw_listh_chief_del(chief, mbr) bsw_listh_del(&(chief)->mbr)

/**
 * 哈希桶结点遍历
 * @node 所遍历结点地址
 * @head 哈希桶结点地址
 */
#define bsw_listh_foreach(node, head)                               \
    for (node=(head)->next; node; node=(node)->next)

/**
 * 哈希桶结点遍历，支持 bsw_listh_del(node)
 * @node 所遍历结点地址
 * @next @node 后向结点地址
 * @head 哈希桶结点地址
 */
#define bsw_listh_foreach_safe(node, nextn, head)                   \
    for (node=(head)->next;                                         \
         node && ({nextn=node->next; 1;});                          \
         node=nextn)

/**
 * 获取哈希表结点所属数据对象地址
 * @node  结点地址
 * @chief 数据对象地址
 * @mbr   数据对象中串联哈希表的结点命名
 */
#define bsw_listh_chief(node, chief, mbr) ({                        \
    (node) ? bsw_startof(node,typeof(*(chief)),mbr) : NULL;         \
})

/**
 * 哈希桶数据对象遍历
 * @chief 所遍历数据对象地址
 * @head  哈希桶首地址
 * @mbr   数据对象中串联哈希表的结点命名
 */
#define bsw_listh_foreach_chief(chief, head, mbr)                   \
    for (chief=bsw_listh_chief((head)->next,chief,mbr);             \
         chief;                                                     \
         chief=bsw_listh_chief(chief->mbr.next,chief,mbr))

/**
 * 哈希桶数据对象遍历，支持 bsw_listh_chief_del(chief)
 * @chief 所遍历数据对象地址
 * @next  @chief 后向数据对象地址
 * @head  哈希桶首地址
 * @mbr   数据对象中串联哈希表的结点命名
 */
#define bsw_listh_foreach_chief_safe(chief, nextn, head, mbr)       \
    for (chief = bsw_listh_chief((head)->next, chief, mbr);         \
         chief &&                                                   \
         ({nextn=bsw_listh_chief(chief->mbr.next,chief,mbr); 1;});  \
         chief = nextn)

#endif